"""
Smart Review Service
"""

import os
import logging
import uuid
import sys
from typing import Optional, Tuple
from datetime import datetime
from pathlib import Path
from dotenv import load_dotenv

from ..models.review_models import ReviewFeedback, ReviewResult

logger = logging.getLogger(__name__)

env_path = Path(__file__).parent.parent.parent / '.env'
load_dotenv(env_path)

hiagent_path = Path(__file__).parent.parent / "llm" / "hiagent-chat"
hiagent_path_str = str(hiagent_path.resolve())

if hiagent_path_str not in sys.path:
    sys.path.insert(0, hiagent_path_str)

HiAgentClient = None
load_config = None

try:
    import importlib.util

    exceptions_spec = importlib.util.spec_from_file_location(
        "hiagent_exceptions",
        hiagent_path / "exceptions.py"
    )
    if exceptions_spec and exceptions_spec.loader:
        exceptions_module = importlib.util.module_from_spec(exceptions_spec)
        sys.modules["hiagent_exceptions"] = exceptions_module
        exceptions_spec.loader.exec_module(exceptions_module)

    models_spec = importlib.util.spec_from_file_location(
        "hiagent_models",
        hiagent_path / "models.py"
    )
    if models_spec and models_spec.loader:
        models_module = importlib.util.module_from_spec(models_spec)
        sys.modules["hiagent_models"] = models_module
        sys.modules["models"] = models_module
        models_spec.loader.exec_module(models_module)

    config_spec = importlib.util.spec_from_file_location(
        "hiagent_config",
        hiagent_path / "config.py"
    )
    if config_spec and config_spec.loader:
        config_module = importlib.util.module_from_spec(config_spec)
        sys.modules["hiagent_config"] = config_module
        sys.modules["config"] = config_module
        config_spec.loader.exec_module(config_module)
        load_config = config_module.load_config

    client_spec = importlib.util.spec_from_file_location(
        "hiagent_client",
        hiagent_path / "client.py"
    )
    if client_spec and client_spec.loader:
        client_module = importlib.util.module_from_spec(client_spec)
        sys.modules["hiagent_client"] = client_module
        sys.modules["client"] = client_module
        client_spec.loader.exec_module(client_module)
        HiAgentClient = client_module.HiAgentClient

    logger.info(f"HiAgent client imported from {hiagent_path_str}")

except Exception as e:
    logger.error(f"Failed to import HiAgent client: {e}", exc_info=True)
    HiAgentClient = None
    load_config = None


class SmartReviewService:
    """Smart Review Service"""

    def __init__(self):
        self.client = None
        self.config = None
        self._initialization_error = None

        if not HiAgentClient or not load_config:
            self._initialization_error = "HiAgentClient or load_config not available"
            logger.error(f"Init failed: {self._initialization_error}")
            return

        try:
            self.config = load_config(from_env=True)

            default_key = os.getenv('HIAGENT_DEFAULT_KEY')
            if default_key:
                self.config.app_key = default_key
                logger.info(f"Using HIAGENT_DEFAULT_KEY: {default_key[:10]}...")

            self.config.timeout = 120

            self.client = HiAgentClient(self.config)
            logger.info(f"SmartReviewService initialized: {self.config.base_url}")

        except Exception as e:
            self._initialization_error = f"Failed to init HiAgentClient: {str(e)}"
            logger.error(self._initialization_error, exc_info=True)
            self.client = None
            self.config = None

    def is_initialized(self) -> bool:
        return self.client is not None

    def get_initialization_error(self) -> Optional[str]:
        return self._initialization_error

    def simple_review(
        self,
        user_id: str,
        question: str,
        grading_criteria: Optional[str],
        student_answer: Optional[str],
        student_answer_file: Optional[str],
        document_name: str = "student_answer.txt"
    ) -> Tuple[bool, Optional[ReviewResult], Optional[str]]:
        """Simple review"""
        try:
            if not student_answer and not student_answer_file:
                return False, None, "Must provide student_answer or student_answer_file"

            answer_content = ""

            if student_answer:
                answer_content = student_answer

            if student_answer_file:
                try:
                    import base64
                    file_bytes = base64.b64decode(student_answer_file)
                    file_text = file_bytes.decode('utf-8', errors='ignore')

                    if answer_content:
                        answer_content += "\n\n---Attachment---\n" + file_text
                    else:
                        answer_content = file_text
                except Exception as e:
                    logger.error(f"File decode failed: {e}")
                    return False, None, f"File decode failed: {str(e)}"

            system_prompt = self._build_system_prompt(question, grading_criteria)

            logger.info(f"Creating review session: user={user_id}")

            inputs = {"system": system_prompt}
            conversation = self.client.create_conversation(user_id=user_id, inputs=inputs)

            logger.info(f"Submitting review: session={conversation.app_conversation_id}")

            start_time = datetime.now()

            query = self._build_query(answer_content)

            response = self.client.chat(
                conversation_id=conversation.app_conversation_id,
                query=query,
                user_id=user_id
            )

            feedback = self._parse_feedback(response.content)

            processing_time = (datetime.now() - start_time).total_seconds()

            review_id = f"review_{uuid.uuid4().hex[:12]}"
            result = ReviewResult(
                review_id=review_id,
                session_id=conversation.app_conversation_id,
                user_id=user_id,
                document_name=document_name,
                feedback=feedback,
                reviewed_at=datetime.now(),
                processing_time=processing_time
            )

            logger.info(f"Review completed: {review_id}, time={processing_time:.2f}s")
            return True, result, None

        except Exception as e:
            error = f"Review error: {str(e)}"
            logger.error(error)
            return False, None, error

    def _build_system_prompt(self, question: str, grading_criteria: Optional[str]) -> str:
        """Build system prompt"""
        prompt = """You are a professional teacher. Please reply in Chinese.

Question:
{question}

{criteria_section}

Please provide detailed review including:
1. Overall grade (0-100)
2. Strengths
3. Weaknesses
4. Corrections
5. Suggestions

Please provide detailed, constructive feedback in Chinese."""

        if grading_criteria:
            criteria_section = f"""Grading Criteria:
{grading_criteria}

Please grade strictly according to the criteria."""
        else:
            criteria_section = "Grading Requirements:\nPlease evaluate comprehensively based on the question and academic standards."

        return prompt.format(
            question=question,
            criteria_section=criteria_section
        )

    def _build_query(self, answer_content: str) -> str:
        """Build query"""
        return f"""Please review the following answer. Reply in Chinese.

---Answer Start---
{answer_content}
---Answer End---

Please provide:
1. Overall grade (0-100)
2. Strengths
3. Weaknesses
4. Corrections
5. Suggestions
"""

    def _parse_feedback(self, full_feedback: str) -> ReviewFeedback:
        """Parse feedback"""
        import re

        grade = None
        grade_match = re.search(r'(?:grade|score|评分|分数)[:：]\s*(\d+)(?:/100)?', full_feedback, re.IGNORECASE)
        if grade_match:
            grade = float(grade_match.group(1))

        strengths = None
        strengths_match = re.search(r'(?:优点|strengths?)[:：\n](.*?)(?=(?:缺点|不足|weaknesses?|建议|suggestions?|改进|corrections?|$))', full_feedback, re.IGNORECASE | re.DOTALL)
        if strengths_match:
            strengths = strengths_match.group(1).strip()

        weaknesses = None
        weaknesses_match = re.search(r'(?:缺点|不足|weaknesses?)[:：\n](.*?)(?=(?:优点|strengths?|建议|suggestions?|改进|corrections?|$))', full_feedback, re.IGNORECASE | re.DOTALL)
        if weaknesses_match:
            weaknesses = weaknesses_match.group(1).strip()

        suggestions = None
        suggestions_match = re.search(r'(?:建议|改进|suggestions?)[:：\n](.*?)(?=(?:优点|strengths?|缺点|weaknesses?|$))', full_feedback, re.IGNORECASE | re.DOTALL)
        if suggestions_match:
            suggestions = suggestions_match.group(1).strip()

        feedback = ReviewFeedback(
            overall_grade=grade,
            strengths=strengths,
            weaknesses=weaknesses,
            suggestions=suggestions,
            detailed_feedback=full_feedback
        )

        return feedback


review_service = SmartReviewService()
